3.2. GDB 命令详细信息

在本节中,我们列出了常见的 GDB 命令并通过示例展示了它们的一些功能。我们首先讨论一些使 GDB 更易于使用的常见键盘快捷键。

3.2.1. GDB键盘快捷键

GDB 支持命令行补全。用户可以输入命令的唯一前缀并按TAB键,GDB 将尝试完成命令行。此外,独特的缩写可用于发出许多常见的 GDB 命令。例如,用户无需输入命令print x,只需输入p x即可打印出x的值,或者l可用于list命令,或者n可用于打印next的值。

向上和向下箭头键 滚动浏览之前的 GDB 命令行,无需每次都重新输入。

在 GDB 提示符下按RETURN键将执行 最近的上一个命令 。当使用一系列nextstep命令逐步执行时,这特别有用;只需按RETURN,GDB 就会执行下一条指令。

3.2.2. 常用GDB命令

我们在这里总结了 GDB 最常用的命令,按照相似的功能对它们进行分组:用于控制程序执行的命令;用于评估程序执行点的命令;设置和控制断点的命令;以及用于打印程序状态和计算表达式的命令。 GDB ‘help’ 命令提供有关所有 GDB 命令的信息:

  • help: GDB 命令的帮助文档。

help <topic or command> 显示可用的帮助主题或命令

help breakpoints 显示有关断点的帮助信息
help print 显示有关打印命令的帮助信息

执行控制流命令

  • break: 设置一个断点。

break <func-name> Set breakpoint at start of function <func-name>
break <line> Set breakpoint at line number <line>
break <filename:><line> Set breakpoint at <line> in file <filename>
break main Set breakpoint at beginning of main
break 13 Set breakpoint at line 13
break gofish.c:34 Set breakpoint at line 34 in gofish.c
break main.c:34 Set breakpoint at line 34 in main.c

在特定文件中指定一行(如break gofish.c:34)允许用户在跨越多个 C 源代码文件(.c 文件)的 C 程序中设置断点。当设置的断点与程序暂停点的代码不在同一文件中时,此功能特别有用。

  • run: 从头开始运行被调试的程序。

run <command line arguments>

run Run with no command line arguments
run 2 40 100 Run with 3 command line arguments: 2, 40, 100

  • continue (cont): 从断点处继续执行

continue

  • step (s): 执行程序 C 源代码的下一行,如果在该行上执行了函数调用,则单步执行函数。

step Execute next line (stepping into a function)
step <count> Executes next <count> lines of program code

step 10 Executes the next 10 lines (stepping into functions)

对于step <count>命令,如果一行包含函数调用,则被调用函数的行将计入count要单步执行的行总数中。因此,step <count>可能会导致程序在从发出step <count>命令的暂停点调用的函数内暂停。

  • next (n): 与step命令类似,但它将函数调用视为单行。换句话说,当下一条指令包含函数调用时,next不会单步执行该函数,而是在函数调用返回后暂停程序(在函数调用后面的代码中的下一行暂停程序)。

next Execute the next line
next <count> Executes next <count> instructions

  • until: 执行程序,直到到达指定的源代码行号。

until <line> Executes until hit line number <line>

  • quit: 退出GDB

quit

用于检查执行点和列出程序代码的命令

  • list: 列出程序源代码。

list Lists next few lines of program source code
list <line> Lists lines around line number <line> of program
list <start> <end> Lists line numbers <start> through <end>
list <func-name> Lists lines around beginning of function <func-name>

list 30 100 List source code lines 30 to 100

  • where (backtracebt): 显示堆栈的内容(程序执行中当前点的函数调用顺序)。where命令有助于查明程序崩溃的位置以及检查函数调用和返回之间接口的状态,例如传递给函数的参数值。

where

  • frame <frame-num>: 进入堆栈帧号<frame-num>的上下文。默认情况下,程序在帧 0(栈顶部的帧)的上下文中暂停。 frame命令可用于移动到另一个堆栈帧的上下文中。通常,GDB 用户移动到另一个堆栈帧来打印另一个函数的参数和局部变量的值。

frame <frame-num> Sets current stack frame to <frame-num>
info frame Show state about current stack frame

frame 3 Move into stack frame 3's context (0 is top frame)

设置和操作断点的命令

break <func-name> Set a breakpoint at start of a function
break <line> Set a breakpoint at a line number
break main Set a breakpoint at start of main
break 12 Set a breakpoint at line 12
break file.c:34 Set a breakpoint at line 34 of file.c

  • enabledisableignoredeleteclear: 启用、禁用、忽略一定次数或删除一个或多个断点。 delete命令按断点编号删除断点。相反,使用clear命令会删除源代码中特定位置的断点。

disable <bnums ...> Disable one or more breakpoints
enable <bnums ...> Enable one or more breakpoints
ignore <bpnum> <num> Don't pause at breakpoint <bpnum> the next <num> times it's hit

delete <bpnum> Delete breakpoint number <bpnum>
delete Deletes all breakpoints
clear <line> Delete breakpoint at line <line>
clear <func-name> Delete breakpoint at function <func-name>

info break List breakpoint info (including breakpoint bnums)
disable 3 Disable breakpoint number 3
ignore 2 5 Ignore the next 5 times breakpoint 2 is hit
enable 3 Enable breakpoint number 3
delete 1 Delete breakpoint number 1
clear 124 Delete breakpoint at source code line 124

  • condition: 在断点上设置条件。条件断点是仅当某个条件成立时才将控制权转移给 GDB 的断点。它可用于仅在一定次数的迭代之后在循环内的断点处暂停(通过在循环计数器变量上添加条件),或者仅当变量的值具有有趣的值时在断点处暂停程序调试目的(避免在其他时间暂停程序)。

condition <bpnum> <exp> Sets breakpoint number <bpnum> to break only when expression <exp> is true

break 28 Set breakpoint at line 28 (in function play)
info break Lists information about all breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483a3 in play at gofish.c:28

condition 1 (i > 1000) Set condition on breakpoint 1

用于检查和评估程序状态和表达式的命令

  • print (p): 显示表达式的值。尽管 GDB 用户通常会打印程序变量的值,但 GDB 将打印任何 C 表达式的值(甚至是不在程序代码中的表达式)。 print命令支持不同格式的打印,并支持不同数值表示的操作数。

print <exp> Display the value of expression <exp>
p i print the value of i
p i+3 print the value of (i+3)

以不同格式打印:

print <exp> Print value of the expression as unsigned int
print/x <exp> Print value of the expression in hexadecimal
print/t <exp> Print value of the expression in binary
print/d <exp> Print value of the expression as signed int
print/c <exp> Print ASCII value of the expression
print (int)<exp> Print value of the expression as unsigned int

print/x 123 Prints 0x7b
print/t 123 Print 1111011
print/d 0x1c Prints 28
print/c 99 Prints 'c'
print (int)'c' Prints 99

要在表达式中指定不同的数字表示形式(数字默认为十进制表示形式):

0x prefix for hex: 0x1c
0b prefix for binary: 0b101

print 0b101 Prints 5 (default format is decimal)
print 0b101 + 3 Prints 8
print 0x12 + 2 Prints 20 (hex 12 is 18 in decimal)
print/x 0x12 + 2 Prints 0x14 (decimal 20 in hexadecimal format)

有时,表达式可能需要显式类型转换来告知print如何解释它们。例如,在这里,在取消引用该地址之前,必须将地址值重新转换为特定类型(int *)(否则,GDB不知道如何取消引用该地址):

print *(int *)0x8ff4bc10 Print int value at address 0x8ff4bc10

当使用print显示取消引用的指针变量的值时,不需要进行类型转换,因为 GDB 知道指针变量的类型并知道如何取消引用其值。例如,如果ptr被声明为int *,它指向的int值可以像这样显示:

print *ptr Print the int value pointed to by ptr

要打印出存储在硬件寄存器中的值:

print $eax Print the value stored in the eax register

  • display: 到达断点时自动显示表达式的值。表达式语法与print命令相同。

display <exp> Display value of <exp> at every breakpoint

display i
display array[i]

  • x (检查内存):显示内存位置的内容。此命令类似于print,但它将其参数解释为地址值,并取消引用该地址值以打印存储在该地址处的值。

x <memory address expression>

x 0x5678 Examine the contents of memory location 0x5678
x ptr Examine the contents of memory that ptr points to
x &temp Can specify the address of a variable
(this command is equivalent to: print temp)

print一样,x可以以不同格式显示值(例如,intchar或字符串)。

检查格式是否固定

粘性格式 (Sticky formatting) 意味着 GDB 会记住当前的格式设置,并将其应用于对不指定格式的后续调用x。例如,如果用户输入命令x/c,则所有后续不格式化的x执行都将使用/c格式。因此,当用户希望更改最近调用x的内存地址单元、重复或显示格式时,只需要使用x命令显式指定格式化选项。

一般来说,x最多需要三个格式化参数(x/nfu <内存地址>);它们列出的顺序并不重要:

  1. n: the repeat count (a positive integer value)

  2. f: the display format (s: string, i: instruction, x: hex, d: decimal, t: binary, a: address, …​)

  3. u: the units format (number of bytes) (b: byte, h: 2 bytes, w: 4 bytes, g: 8 bytes)

以下是一些示例(假设 s1 ="Hello There"位于内存地址0x40062d):

x/d   ptr       Print value stored at what ptr points to, in decimal
x/a   &ptr      Print value stored at address of ptr, as an address
x/wx  &temp     Print 4-byte value at address of temp, in hexadecimal
x/10dh  0x1234  Print 10 short values starting at address 0x1234, in decimal

x/4c s1         Examine the first 4 chars in s1
    0x40062d   72 'H'  101 'e'  108 'l'  108 'l'

x/s s1         Examine memory location associated with var s1 as a string
    0x40062d   "Hello There"

x/wd s1        Examine the memory location assoc with var s1 as an int
                (because formatting is sticky, need to explicitly set
                units to word (w) after x/s command sets units to byte)
    0x40062d   72

x/8d s1        Examine ASCII values of the first 8 chars of s1
    0x40062d:  72  101 108 108 111 32  84  104
  • whatis: 显示表达式的类型。

whatis <exp> Display the data type of an expression

whatis (x + 3.4) Displays: type = double

  • set: 分配/更改程序变量的值,或分配要存储在特定内存地址或特定机器寄存器中的值。

set <variable> = <exp> Sets variable <variable> to expression <exp>

set x = 123 * y Set var x's value to (123 * y)

  • info: 列出有关程序状态和调试器状态的信息。有大量的info选项用于获取有关程序当前执行状态和调试器的信息。一些例子包括:

help info Shows all the info options
help status Lists more info and show commands

info locals Shows local variables in current stack frame
info args Shows the argument variable of current stack frame
info break Shows breakpoints
info frame Shows information about the current stack frame
info registers Shows register values
info breakpoints Shows the status of all breakpoints

有关这些和其他 GDB 命令的更多信息,请参阅 GDB 手册页 (man gdb) 和 GNU 调试器主页